﻿/// <reference path="jquery.js" />

/**
* 这个是对ajax的调用进行进一步的封装，统一的处理函数进行回调时，失败的处理
* 这块是client和mobile公用的模块
* 所有的ajax的调用都是使用先注册在调用的方式。
*/


/**
 * ajax请求类型封装
 * @param type string 请求类型（请求的url地址）
 * @param validparm function 用于进行参数验证的函数 必须要有返回值 返回值为bool
 * @param successfunc function 请求成功后的处理方式（default）
 * @param failfunc function 请求失败后的处理方式（default）
 */

var ajaxManager = function () {
    function Error(msg) {
        this.message = msg;
    }

    function emptyfunc() {

    }

    function AjaxRequestType(type, validparm, successfunc, failfunc) {
        this.type = type;
        if (validparm && typeof validparm !== "function") throw new Error("验证参数必须为function 或 为空");
        this.valid = validparm;
        if (!successfunc || typeof successfunc !== "function") throw new Error("成功回调必须为function");
        this.successfunc = successfunc;
        if (!failfunc || typeof failfunc !== "function") throw new Error("失败回调必须为function");
        this.failfunc = failfunc;
    }

    
    /**
    * 对ajax进行统一调度和管理的类
    * */
    function AjaxManager() {
        this.type = {};
        this.errordisposefunc = null;//请求出错的处理方式
    }

    /**
    * 全局对象 主要是在client端使用，当网络断开是，所有的ajax请求均不允许进行调用
    * */
    AjaxManager.socketState = true;

    /**
     * 注册ajax请求类别
     * @param type string 请求类型（url）
     * @param validparm function 用于进行参数验证的函数
     * @param successfunc function 请求成功后的处理方式（default）
     * @param failfunc function 请求失败后的处理方式（default）
     */
    AjaxManager.prototype.AddRequestType = function (type, validparm, successfunc, failfunc) {
        if (typeof type == "string") {
            this.type[type] = new AjaxRequestType(type, validparm, successfunc, failfunc);
        }
    }

    /**
     * 供外部调用的ajax请求
     * @param type string 已经进行注册的请求
     * @param parm object 请求需要传递到服务器端的参数
     * @param option object 与当前请求绑定的参数在请求成功或失败后的回调函数中可以取到
     */
    AjaxManager.prototype.Request = function (type, parm, option) {
        var promise;
        if (!type || !this.type[type]) {
            //show_tip("请求类型错误");
            var err = this.errordispose(option, new Error("请求类型错误"));
            promise = $.Deferred();
            promise.Cancel = emptyfunc;
            promise.reject(option, err);
            //return promise;
        }
        else {
            type = this.type[type];
            if (type.valid && !type.valid(parm)) {
                var err = this.errordispose(option, new Error("请求参数错误"));
                promise = $.Deferred();
                promise.Cancel = emptyfunc;
                promise.reject(option, err);
            } else {
                //如果请求的参数中包含有url则直接使用parm作为ajax请求的参数集合
                var reqparm;
                if (typeof parm === "object" && parm.url) {
                    reqparm = parm;
                    reqparm.timeout = reqparm.timeout || 300000;
                } else {
                    reqparm = {
                        url: type.type,//"/dataserver/" + type.type,
                        type: "post",
                        data: parm,
                        timeout:130000
                    };
                }
                promise = this.baseRequest(reqparm, option);
            }
            promise.done(type.successfunc).fail(type.failfunc);
        }
        promise.success = promise.done;
        promise.error = promise.fail;
        return promise;
    }

    /**
     * 基本ajax请求，仅供内部调用
     * @param parm object $.ajax调用时的参数请求
     * @param option 与请求绑定的状态 回调时使用
     */
    AjaxManager.prototype.baseRequest = function (parm, option) {
        var promise = $.Deferred();
        var self = this;
        if (AjaxManager.socketState == 0) {
            //表示断线
            var err = this.errordispose(option, new Error("网络连接错误"));
            promise.Cancel = emptyfunc;
            promise.reject(option, err);
        } else {
            var ajax = $.ajax(parm).success(function (data) {
                if (data.Ok) {
                    promise.resolve(option, data.data);
                } else {
                    var err = self.errordispose(option, new Error(data.data));
                    promise.reject(option, err);
                }
            }).fail(function (error) {
                var err = self.errordispose(option, new Error("请求服务失败"));
                promise.reject(option, err);
            });
            promise.abort = function () { ajax.abort(); }; //function (req) { return function () { req.abort(); } }(ajax);  // ajax.abort();
            promise.Cancel = promise.abort;
        }
        return promise;
    }
    /**
     * 请求错误处理函数
     * @param option object 与请求绑定的option来源于request的option
     * @param err error 系统error对象，主要携带了错误信息
     */
    AjaxManager.prototype.errordispose = function (option, err) {
        if (this.errordisposefunc && typeof this.errordisposefunc === "function") {
            err = this.errordisposefunc(option, err) || err;
        } else {
//          console.error(err); 
        }
        return err;
    }

    /**
     * 不进行参数的验证操作(主要用于请求注册)
     */
    AjaxManager.novalid = function () {
        return true;
    }

    ajaxManager = new AjaxManager();


    ajaxManager.GetSocketState = function () {
        return AjaxManager.socketState;
    }
    ajaxManager.SetSocketState = function (state) {
        AjaxManager.socketState = state;
    }
    ajaxManager.UnValid = AjaxManager.novalid;

    return ajaxManager;
}();
